<?php
 class Parse{
        private $_tpl;//use save tpl_file content
        
        public function __construct($tpl_file){
            if(!$this->_tpl  =   file_get_contents($tpl_file)){
                exit("the tpl content read error");
            }
        }
        //compile()方法：完成静态模板的解析并生成编译文件
        public function compile($parse_file,$tpl_file){
            $this->parse();//调用私有方法parse()完成各种标签的解析
            //如果编译文件不存在或是模板文件被修改过就生成编译文件
            if(!file_exists($parse_file)||filemtime($tpl_file)>=filemtime($parse_file)){
              if(!file_put_contents($parse_file,$this->_tpl)){
                    exit('compile error!');
                }
            }
        }
        private function parse(){
            $this->parseInclude();
            $this->parsePublic();
            $this->parseLang();
            $this->parseCommon();
            $this->parseForeach();
            $this->parseVar();
            $this->parseIf();
        }
        private function parsePublic(){
            $mode   =   '/__PUBLIC__/';
            if(preg_match($mode,$this->_tpl)){
                $this->_tpl =   preg_replace($mode,"<?php echo APP_PUBLIC;?>",$this->_tpl);//change the tpl_var
            }
        }
        private function parseVar(){
            $mode   =   '/\{\$([\w]+)\}/';
            if(preg_match($mode,$this->_tpl)){
                $this->_tpl =   preg_replace($mode,"<?php echo \$this->_vars['$1'];?>",$this->_tpl);//change the tpl_var
            }
        }
        private function parseIf(){
            $modeIf         =   '/\{if\s+\$([\w]+)\}/';
            $modeEndIf   =   '/\{\/if\}/';
            $modeElse     =   '/\{else\}/';
            if(preg_match($modeIf,$this->_tpl)){
                if(preg_match($modeEndIf,$this->_tpl)){
                    $this->_tpl =   preg_replace($modeIf,"<?php if(\$this->_vars['$1']){?>",$this->_tpl);
                    $this->_tpl =   preg_replace($modeEndIf,"<?php }?>",$this->_tpl);
                    if(preg_match($modeElse,$this->_tpl)){
                        $this->_tpl =   preg_replace($modeElse,"<?php }else{?>",$this->_tpl);
                    }
                }else{
                    exit("haven't {/if}");
                }
            }
        }
        private function parseInclude(){
            $mode   =   '/\{include\s+file=\"(.*)\"\}/';
            if (preg_match_all ( $mode, $this->_tpl, $file )) {
                $include_file=nulll;
                foreach($file[1] as $k=>$v){
                    if($v[0]=='/'){
                        $v =   APP_DIR.'/view'.$v;
                    }else{
                        $v = TPL_DIR.$v;//set want load templates url
                    }
                    if (! file_exists ( $v )) {
                        exit ( 'the include file is error!' );
                    }else{
                        $include_file=file_get_contents($v);
                    }
                    //加载包含文件的内容
                    $modeOne    =    $file[0][$k];
                    $this->_tpl = str_replace ( $modeOne,$include_file, $this->_tpl ); //替换成相应的php语言中的include包含语句
                }
            }
        }
        private function parseCommon(){
            $mode='/{#\s+(.*)\s+#}/';//注释标签模式
            //在模板文件中匹配模式,如果匹配成功,则替换成相应的php语言中的注释
            if(preg_match($mode,$this->_tpl)){
            $this->_tpl=preg_replace($mode,"<?php /* '$1' */?>",$this->_tpl);//替换成相应的php语言中的注释
            }
        }
        private function parseLang(){
            $mode   =   '/\{\$lang\.([\w]+)\}/';
            if(preg_match($mode,$this->_tpl)){
                $this->_tpl =   preg_replace($mode,"<?php echo \$this->_langs['$1'];?>",$this->_tpl);
            }
        }
        //parseForeach()方法：解析foreach语句
        private function parseForeach(){
            //foreach语句匹配模式
            $modeForeach='/\{foreach\s+key=([\w]+)\s+item=([\w]+)\s+from=\$([\w]+)\}/';
            $modeEndForeach='/\{\/foreach\}/';
            $modeVar='/\{@([\w]+)\}/';
            //在模板文件中匹配模式,如果匹配成功,则替换成相应的php语言中的foreach语句
            if(preg_match($modeForeach,$this->_tpl)){
                if(preg_match($modeEndForeach,$this->_tpl)){
                    $this->_tpl=preg_replace($modeForeach,"<?php foreach(\$this->_vars['$3'] as \$$1=>\$$2){?>",$this->_tpl);
                    $this->_tpl=preg_replace($modeVar,"<?php echo \$$1;?>",$this->_tpl);
                    $this->_tpl=preg_replace($modeEndForeach,"<?php }?>",$this->_tpl);
                }else{
                    exit('Foreach语句没有关闭!');
                }
            }
        }
}
?>